/**
 * 
 */
package weibo4j.crawler.publictimelinecrawler;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;

import weibo4j.Comment;
import weibo4j.Paging;
import weibo4j.RateLimitStatus;
import weibo4j.Status;
import weibo4j.Weibo;
import weibo4j.WeiboException;
import weibo4j.database.DataBaseUtil;

/**
 * @author longrui
 * 
 */
public class PublicTimeLineCrawler {
	private Weibo weibo;
	private LinkedBlockingQueue<String> SQLStringQueue;
	private List<Status> ret;

	private final static String statusTable = "public_time_line_statuses";

	private long sleepTime;

	private long adjustFreq() throws InterruptedException,
			WeiboException {
			RateLimitStatus rateLimitStatus = weibo.getRateLimitStatus();
		
			long remainingHits = rateLimitStatus.getRemainingHits();
			long resetTimeInSeconds = rateLimitStatus.getResetTimeInSeconds();
			if (remainingHits == 0) {
				this.sleepTime = resetTimeInSeconds * 1000;
			} else {
				// 计算
				long sleep = resetTimeInSeconds * 1000 / remainingHits;
				if (sleep <= 0)
					sleep = 1;
				sleepTime = sleep;
			}
		return sleepTime;
	}


	class DBWriter extends Thread {
		private Connection conn;

		public DBWriter(Connection conn) {
			this.conn = conn;
		}

		public void run() {
			while (true) {
				try {
					prepareStore();
					int i = 0;
					while (i < 1000) {
						String sql = SQLStringQueue.take();
						System.err.println("sql: " + sql);
						DataBaseUtil.executeStatement(conn, sql);
						i++;
					}
					System.err.println(new Date());
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}
		}
	};

	private DBWriter dbWriter; // DataBase Writer

	public PublicTimeLineCrawler(String id, String passwd) {
		this.weibo = new Weibo(id, passwd);
		SQLStringQueue = new LinkedBlockingQueue<String>();
		ret = null;
		dbWriter = new DBWriter(DataBaseUtil.getDefaultConnection());

		// 默认请求之前等待3.5秒钟，此值根据每小时1000次的限制算得（每次3.6秒),
		// 鉴于日志操作也有等待时间，故此值应能保证请求次数不超限
		sleepTime = 3000;
	}

	public void prepareStore() throws InterruptedException {
		synchronized (this) {
			while (SQLStringQueue.size() < 1000)
				wait();
		}
	}

	public synchronized void go() {
		notifyAll();
	}

	public LinkedBlockingQueue<String> getSQLStringQueue() {
		return SQLStringQueue;
	}

	public void run() {
		dbWriter.start();
		while (true) {
			try {
				ret = weibo.getPublicTimeline();
				Thread.sleep(adjustFreq());
				System.out.println("result size: " + ret.size() + " SQLStringQueue size: " +SQLStringQueue.size());
				for (Status status : ret) {
					SQLStringQueue.add(status.getStatusSQLString(statusTable,"utf-8"));
				}
				go();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
	}
}
